// ======================================================================
// Copyright (C) 2013 Hell-Prototypes. / www.hellprototypes.com
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// ======================================================================
#ifndef PAP_THREAD_H
#define PAP_THREAD_H

#include <QThread>
#include <QMap>
#include "pap_thread.h"
#include "define.h"
#include "usb.h"

class pap_thread : public QThread
{
    Q_OBJECT
public:
    explicit pap_thread(QObject *parent = 0);
    virtual ~pap_thread();

    //usb
    usb_dev_handle *m_usb_dev; /* the device handle */
    bool usb_connect_ctrl();
    void usb_auto_connect_ctrl();

    //move
    bool init_arm_position();
    bool move_arm_to(const iPoint &target_pos, int delay = 0);
    bool picker_move_up();
    bool picker_move_to_top();
    bool place_picker_move_down();
    bool pick_picker_move_down();
    bool set_move_speed(int speed);
    bool move_arm_to_origin();
    bool move_cam_to_feeder_zone(const iPoint &zone_center);
    void set_move_param(part_t &part, DPoint &place_coor, double &target_orient);
    bool stepmotor_enable_ctrl(bool active);

    bool turn_pump_on(bool on);

    bool set_picker_angle(double angle);
    bool set_picker_updown(double angle);
    bool set_picker_offset(int offset_x, int offset_y);

    //variable
    iPoint m_curr_arm_pos;
    QMap <int, pcb_mark_param> m_pcb_mark_list;

    //Transform
    iPoint pixel_coor_to_arm_arg(const Point &p_pixel);
    bool place_coor_to_arm_arg(const DPoint *p_coor, iPoint &arm_arg);
    double distance_of_2_point(double x0, double y0, double x1, double y1);

    //misc
    void set_image_size(int w, int h);
    void set_only_pickup_flag(bool flag)         { m_only_pickup_part = flag;   }
    void set_cam_width_length_mm(double len)     { m_cam_width_length_mm = len; }

protected:
     void run();

signals:
    void disp_system_msg(QString msgs);
    void xy_axis_pos(int x, int y);
    void pap_error_process(int error_code);
    void usb_connected();
    void controller_status_update(int status);

public slots:

private:
     int m_cam_image_width;
     int m_cam_image_height;
     int m_move_speed;
     double m_cam_width_length_mm;
     iPoint m_feeder_zone_center;

     part_t m_move_param_part;
     DPoint m_move_param_place_coor;
     double m_move_param_target_orient;

     bool m_only_pickup_part;

     int m_picker_offset_x;
     int m_picker_offset_y;

     /*usb function*/
     usb_dev_handle* open_dev(void);
     bool send_ctrl_cmd(char *cmd_data, int cmd_len);
     int usb_Ctrl_CMD(const char command, const uint param);
     int read_bulk_data(char *rd_buffer, int len);
     void usb_boot_2nd_app();

     //motor
     int angle_to_duty(double angle);
     bool set_servo_angle(uint ch, double angle);
 //  bool stop_arm_driver();
     bool move_x_axis(int distance);
     bool move_y_axis(int distance);
     int get_controller_status();

     //pick and place
     bool pick_up_one_part(const part_t &part);
     //bool adjusting_part_orient(double target_orient);
     bool place_one_part(DPoint &place_coor);
};

#endif // PAP_THREAD_H
